(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('node:fs'), require('node:path'), require('node:os'), require('node:child_process')) :
    typeof define === 'function' && define.amd ? define(['exports', 'node:fs', 'node:path', 'node:os', 'node:child_process'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.mvcommon = {}, global.fs, global.path, global.os, global.node_child_process));
})(this, (function (exports, fs, path, os, node_child_process) { 'use strict';

    /**
     * 判断一个url是不是有有效的http格式
     * @param { string } url 链接地址
     * @returns { boolean } 是否是一个链接
     * **/
    const isValidUrl = (url) => {
        return /^(http|https):\/\//.test(url);
    };
    /**
     * 获取一个数据的类型
     * @param { unknown } value 需要判断类型的数据
     * @returns { string | null } 判断的数据类型
     * **/
    const getType = (value) => {
        const typeResult = Object.prototype.toString.call(value);
        const type = typeResult
            .slice(typeResult.indexOf(' ') + 1, -1)
            .toLocaleLowerCase();
        if (type === 'array') {
            if (Array.isArray(value))
                return 'array';
            else
                return null;
        }
        return type;
    };
    /**
     * 判断一个数据的类型是否为指定的类型
     * @param { unknown } value 需要判断类型的数据
     * @param { string | Array } type 期望的数据类型
     * @return { boolean } 是否为期望的类型
     * **/
    const isType = (value, type) => {
        const valueType = getType(value);
        if (valueType === null)
            throw new Error('invalid value...');
        if (typeof type === 'string')
            return valueType === type.toLocaleLowerCase();
        return type.map((item) => item.toLocaleLowerCase()).includes(valueType);
    };
    /**
     * 异步或同步延迟等待一段时间
     * @param { number } timeout 等待时常，默认为 1S钟
     * @param { boolean } sync 是否同步
     * @returns { Promise<boolean> } 异步，是否执行完成
     * **/
    const sleep = (timeout = 1000, sync = false) => {
        if (!sync) {
            return new Promise((resolve) => {
                const timer = setTimeout(() => {
                    clearTimeout(timer);
                    resolve(true);
                }, timeout);
            });
        }
        else {
            return Promise.resolve(true);
        }
    };
    /**
     * 防抖方法
     * @param { (...rest: Array<unknown>) => unknown } cb 方法
     * @param { number } delay 防抖延迟时常, 默认为: 0
     * @param { boolean } immediate 是否需要立即执行，默认为: false
     * **/
    const debounce = (cb, delay = 0, immediate = false) => {
        let timer;
        return function (...rest) {
            clearTimeout(timer);
            if (!timer && immediate)
                cb.apply(this, rest);
            const handler = () => {
                clearTimeout(timer);
                timer = null;
                if (!immediate)
                    cb.apply(this, rest);
            };
            timer = setTimeout(handler, delay);
            if (immediate && !timer)
                cb.apply(this, rest);
        };
    };
    /**
     * 节流方法
     * @param { (...rest: Array<unknown>) => unknown } cb 方法
     * @param { number } delay 节流延迟时常, 默认值为: 0
     * **/
    const throttle = (cb, delay = 0) => {
        let loading = false;
        return function (...rest) {
            if (!loading)
                cb.apply(this, rest);
            loading = true;
            const timer = setTimeout(() => {
                clearTimeout(timer);
                loading = false;
            }, delay);
        };
    };
    /**
     * 查看属性是否存在(原型链方式判断)
     * @param { object } value 需要判断的值
     * @param { string } attr key 值
     * **/
    const hasProperty = (value, attr) => {
        return Reflect.has(value, attr);
    };

    /**
     * 从一个字符串中查找指定的字符是否存在
     * @param { string } str 需要查找的字符串
     * @param { Array<string> | string } ident 查找的字符串内容，可以是字符串，也可以是字符串数组
     * @param { boolean } absolute 是否绝对匹配
     * @returns { boolean } 是否可以查询到结果
     * **/
    const findString = (str, ident, absolute = false) => {
        if (isType(ident, 'array')) {
            const findFunction = absolute
                ? (item) => !str.includes(item)
                : (item) => str.includes(item);
            const result = ident.find(findFunction);
            return absolute ? !result : !!result;
        }
        return !!str.includes(ident);
    };

    var src = {exports: {}};

    (function (module, exports) {
    	Object.defineProperty(exports, "__esModule", { value: true });
    	exports.isPlainObject = exports.clone = exports.recursive = exports.merge = exports.main = void 0;
    	module.exports = exports = main;
    	exports.default = main;
    	function main() {
    	    var items = [];
    	    for (var _i = 0; _i < arguments.length; _i++) {
    	        items[_i] = arguments[_i];
    	    }
    	    return merge.apply(void 0, items);
    	}
    	exports.main = main;
    	main.clone = clone;
    	main.isPlainObject = isPlainObject;
    	main.recursive = recursive;
    	function merge() {
    	    var items = [];
    	    for (var _i = 0; _i < arguments.length; _i++) {
    	        items[_i] = arguments[_i];
    	    }
    	    return _merge(items[0] === true, false, items);
    	}
    	exports.merge = merge;
    	function recursive() {
    	    var items = [];
    	    for (var _i = 0; _i < arguments.length; _i++) {
    	        items[_i] = arguments[_i];
    	    }
    	    return _merge(items[0] === true, true, items);
    	}
    	exports.recursive = recursive;
    	function clone(input) {
    	    if (Array.isArray(input)) {
    	        var output = [];
    	        for (var index = 0; index < input.length; ++index)
    	            output.push(clone(input[index]));
    	        return output;
    	    }
    	    else if (isPlainObject(input)) {
    	        var output = {};
    	        for (var index in input)
    	            output[index] = clone(input[index]);
    	        return output;
    	    }
    	    else {
    	        return input;
    	    }
    	}
    	exports.clone = clone;
    	function isPlainObject(input) {
    	    return input && typeof input === 'object' && !Array.isArray(input);
    	}
    	exports.isPlainObject = isPlainObject;
    	function _recursiveMerge(base, extend) {
    	    if (!isPlainObject(base))
    	        return extend;
    	    for (var key in extend) {
    	        if (key === '__proto__' || key === 'constructor' || key === 'prototype')
    	            continue;
    	        base[key] = (isPlainObject(base[key]) && isPlainObject(extend[key])) ?
    	            _recursiveMerge(base[key], extend[key]) :
    	            extend[key];
    	    }
    	    return base;
    	}
    	function _merge(isClone, isRecursive, items) {
    	    var result;
    	    if (isClone || !isPlainObject(result = items.shift()))
    	        result = {};
    	    for (var index = 0; index < items.length; ++index) {
    	        var item = items[index];
    	        if (!isPlainObject(item))
    	            continue;
    	        for (var key in item) {
    	            if (key === '__proto__' || key === 'constructor' || key === 'prototype')
    	                continue;
    	            var value = isClone ? clone(item[key]) : item[key];
    	            result[key] = isRecursive ? _recursiveMerge(result[key], value) : value;
    	        }
    	    }
    	    return result;
    	} 
    } (src, src.exports));

    var srcExports = src.exports;

    /**
     *
     * 是否是一个空对象
     * @param { Object } value 需要判断的数据
     * @returns { boolean } 是否为空对象
     * **/
    const isEmptyJSON = (value) => {
        if (!isType(value, 'object'))
            throw new Error('invalid isEmptyJSON parameter');
        return !Object.keys(value).length;
    };
    /**
     * 扁平化一个JSON对象
     * @param { Object } obj 需要扁平化的对象
     * @returns { Object } 返回扁平化之后的JSON对象
     * **/
    const flatJSON = (obj) => {
        let value = {};
        for (const key in obj) {
            const item = obj[key];
            if (isType(item, 'object')) {
                value = srcExports.recursive(true, value, flatJSON(item));
            }
            else {
                value[key] = item;
            }
        }
        return value;
    };
    /**
     * 将一个JSON对象按照指定的分隔符，拼接为特定的字符串
     * @param { Object } content 内容
     * @param { string } sep 分隔符字符串, 默认为空字符串
     * @return { string } 处理完成之后的字符串
     * **/
    const splitJsonToContent = (content, sep = '') => {
        content = flatJSON(content);
        let fileContent = '';
        for (const key in content) {
            fileContent += `${key}${sep}${content[key]}\n`;
        }
        return fileContent;
    };

    /**
     * 是否是一个空数组
     * @param { Array<unknown> } value 需要判断的数据
     * @returns { boolean } 是否为空数组
     * **/
    const isEmptyArray = (value) => {
        if (!isType(value, 'array'))
            throw new Error('invalid isEmptyArray parameter');
        else
            return !value.length;
    };
    /**
     * 判断一个数据或一组数据均为指定的类型
     * @param { string } type 类型名称  array、object 等使用原型链判断的类型末尾小写
     * @param { Array } args 需要判断的数据
     * @returns { boolean } 一个数据或一组数据是否均为指定的类型
     * **/
    const validType = (type, ...args) => {
        return !args.find((item) => !isType(item, type));
    };
    /**
     * 交集方法
     * @param { Array<Array<unknown>> } args 数据列表
     * @returns { Array<unknown> } 交集数组
     * **/
    const intersectionArrayList = (...args) => {
        return args.reduce((acc, array) => {
            return acc.filter((item) => array.includes(item));
        });
    };
    /**
     * 差集方法
     * @param { Array<unknown> } baseArray  求差集的基准列表
     * @param { Array<unknown> } args 差集列表
     * @returns { Array<unknown> } 差集
     * **/
    const differenceArrayList = (baseArray, ...args) => {
        const otherElementsSet = new Set(...args);
        return baseArray.filter((item) => !otherElementsSet.has(item));
    };
    /**
     * 并集方法
     * @param { Array<Array<unknown>> } args  求并集的数组
     * @returns { Array<unknown> } 并集数组
     * **/
    const unionArrayList = (...args) => {
        return [...new Set(args.flat(1))];
    };

    /**
     * 包版本管理器配置对照表
     * **/
    const packageMangerViewer = new Map([
        ['yarn', 'yarn.lock'],
        ['npm', 'package-lock.json'],
        ['pnpm', 'pnpm-lock.yaml']
    ]);
    /**
     * 获取当前项目的包版本管理器, 目前支持 yarn|npm|pnpm
     * @param { string } targetPath 目标路径
     * **/
    const getPackageMangerName = (targetPath = process.cwd()) => {
        for (const [key, value] of packageMangerViewer) {
            if (fs.existsSync(path.resolve(targetPath, value))) {
                return key;
            }
        }
    };

    /**
     * 使用子进程执行一条命令
     * @param { string } command 执行的命令
     * @param { Partial<SpawnSyncOptionsWithStringEncoding> } options 执行命令的参数
     * **/
    const execCommand = (command, options = {}) => {
        return new Promise((resolve, reject) => {
            const commandList = command.split(' '), spawnOption = Object.assign({
                shell: true,
                encoding: 'utf8',
                cwd: process.cwd()
            }, options);
            if (!fs.existsSync(spawnOption.cwd || ''))
                return reject('exec command cwd is not exists...');
            const result = node_child_process.spawnSync(commandList[0], commandList.slice(1), spawnOption);
            const stdout = result.stdout?.trim?.();
            const error = result.error || result.stderr;
            if (error && findString(error, ['error', 'Error', 'fatal:']))
                return reject(error);
            else
                return resolve(stdout);
        });
    };
    /**
     * 获取系统信息
     * @returns { string } platform 系统平台
     * @returns { string } digit 系统位数
     * @returns { boolean } isWindow 是否是windows系统
     * @returns { boolean } isMac 是否时mac系统
     * @returns { boolean } isWin64 是否是win64
     * @returns { boolean } isWin32 是否是win32
     * **/
    const getSystemInfo = () => {
        const platform = process.platform;
        const systemDigit = process.arch;
        return {
            platform,
            digit: systemDigit,
            isWindow: platform === 'win32',
            isMac: platform === 'darwin',
            isWin64: systemDigit === 'x64',
            isWin32: systemDigit !== 'x64'
        };
    };
    /**
     * 获取当前系统用户的家目录
     * **/
    const getHome = () => {
        return os.homedir();
    };
    /**
     * 获取系统的 appData目录
     * **/
    const getAppData = () => {
        const homedir = getHome();
        return getSystemInfo().isWindow
            ? path.resolve(homedir, 'AppData/Roaming')
            : getSystemInfo().isMac
                ? path.join(homedir, '/')
                : path.resolve(__dirname);
    };
    /**
     * 根据appData目录为基准，获取路径
     * @param { string } refer 参照路径
     * **/
    const getReferToAppData = (refer) => {
        return path.resolve(getAppData(), refer || '');
    };
    /**
     * 根据进程的名称，模糊查询，获取进程的PID
     * @param { string } name 进程的名称
     * **/
    const getPidByName = (name) => {
        const isWindows = getSystemInfo().isWindow;
        const command = isWindows ? 'tasklist' : 'ps -ef';
        const pidList = [];
        return new Promise((resolve) => {
            execCommand(command)
                .then((result) => {
                const lines = result.split(isWindows ? '\r\n' : '\n');
                for (let i = 0; i < lines.length; i++) {
                    if (lines[i].includes(name)) {
                        const columns = lines[i].split(/\s+/);
                        const pid = isWindows ? columns[1] : columns[2];
                        pidList.push(parseInt(pid));
                    }
                }
                resolve(pidList.filter((item) => item));
            })
                .catch(() => {
                resolve([]);
            });
        });
    };
    /**
     * 提供进程的名称，模糊查询进程是否存在
     * @param  { string } processName 进程名称
     * **/
    const isActiveProcessByName = async (processName) => {
        const processList = await getPidByName(processName);
        return !!processList.length;
    };
    /**
     * 提供一个PID，查看这个PID是否正在运行
     * @param {string} pid 进程ID
     * **/
    const isActiveProcessByPid = async (pid) => {
        const isWindow = getSystemInfo().isWindow;
        const command = isWindow ? `tasklist /FI "PID eq ${pid}"` : 'ps -p ${pid}';
        return new Promise((resolve) => {
            execCommand(command)
                .then((res) => {
                resolve(res.includes(pid));
            })
                .catch(() => {
                resolve(false);
            });
        });
    };
    /**
     * 根据进程的PID，结束此进程
     * @param { number | Array<number> } pid 进程PID
     * **/
    const killProcessPid = (pid) => {
        if (!pid)
            return Promise.resolve(false);
        if (!isType(pid, 'array'))
            pid = [pid];
        const tasks = [], isWindows = getSystemInfo().isWindow;
        function killTak(id) {
            const killCommand = isWindows
                ? `taskkill /F /PID ${id}`
                : `kill -9 ${id}`;
            return new Promise((resolve) => {
                node_child_process.exec(killCommand, (err) => {
                    if (err) {
                        resolve(false);
                        return;
                    }
                    resolve(true);
                });
            });
        }
        pid.forEach((id) => tasks.push(killTak(id)));
        return Promise.all(tasks);
    };
    /**
     * 提供进程的名称，结束掉此进程，名称会模糊查询
     * @param { string } processName 进程的名称
     * **/
    const killProcessName = (processName) => {
        return getPidByName(processName).then((list) => {
            list.forEach((pid) => {
                killProcessPid(pid);
            });
            return list;
        });
    };

    /**
     * 查看一个文件或目录是否在指定的路径下存在
     * @param { string } filename 文件名称
     * @param { string } cwd 工作目录，默认值为: 当前工作目录
     * @returns { boolean } 是否存在
     * **/
    const exists = (filename, cwd = process.cwd()) => {
        return fs.existsSync(path.resolve(cwd, filename));
    };
    /**
     * 浅层读取一个目录下的文件或者文件夹
     * @param { string } targetPath 目标路径
     * @param { string } type 文件类型，默认值为: 全部类型
     * @return { Array<string> } 文件列表
     * **/
    const readForTypeFileDir = (targetPath, type = 'all') => {
        const list = fs.readdirSync(targetPath);
        if (type === 'all')
            return list;
        return list.filter((item) => {
            const itemPath = path.resolve(targetPath, item);
            const stat = fs.statSync(itemPath);
            if (typeof type !== 'string')
                return type(itemPath, stat);
            return type === 'file' ? !stat.isDirectory() : stat.isDirectory();
        });
    };
    /**
     * 创建一个目录(仅支持目录)
     * @param { string } targetPath 目标路径
     * @param { boolean } cover 是否覆盖创建 默认值为: false
     * **/
    const createDir = (targetPath, cover = false) => {
        if (fs.existsSync(targetPath)) {
            if (!cover)
                return;
            fs.rmSync(targetPath, { recursive: true });
        }
        fs.mkdirSync(targetPath, { recursive: true });
    };
    /**
     * 写入的一个文件(仅支持文件)
     * @param { string } targetPath 目标路径
     * @param { string } content 文件内容
     * @param { boolean } cover 是否覆盖创建，默认值为: false
     * **/
    const createFile = (targetPath, content, cover = false) => {
        if (fs.existsSync(targetPath)) {
            if (!cover)
                return;
            fs.unlinkSync(targetPath);
        }
        const dirPathName = path.dirname(targetPath);
        if (!fs.existsSync(dirPathName))
            createDir(dirPathName);
        fs.writeFileSync(targetPath, content, { encoding: 'utf-8' });
    };
    /**
     * 当文件存在时，读取一个文件的文件内容
     * @param { string } targetPath 目标文件路径的
     * @param { Parameters<typeof fs.readFileSync>[1] } options 读取时需要传递的参数
     * @returns { string | Buffer } 返回的文件内容
     * **/
    const readExistsFile = (targetPath, options = {}) => {
        if (!fs.existsSync(targetPath))
            return '';
        return fs.readFileSync(targetPath, options);
    };
    /**
     * 移动工具类，此方法仅适用文件的移动
     * @param { string } sourcePath 需要拷贝的路径
     * @param { string } targetPath 目标路径
     * @param { boolean } cover 是否强制覆盖
     * @returns { number } type 移动是否成功: 1 | 0
     * @returns { string } sourcePath 源路径
     * @returns { string } targetPath 目标路径
     * **/
    const copyFile = (sourcePath, targetPath, cover = false) => {
        if (!fs.existsSync(targetPath) || cover) {
            fs.copyFileSync(sourcePath, targetPath);
            return { type: 1, sourcePath, targetPath };
        }
        return { type: 0, sourcePath, targetPath };
    };
    /**
     * 拷贝整个目录及其子路径至指定的目录
     * @param { string } origin 源路径
     * @param { string } targetPath 目标路径
     * @param { ((sourcePath: string, targetPath: string) => boolean) | boolean } cover 是否覆盖
     * @param { ((sourcePath: string, targetPath: string) => boolean) | boolean } ignore 是否忽略
     * **/
    const copyDirectory = async (origin, targetPath, cover = true, ignore = false) => {
        const originStat = fs.statSync(origin).isDirectory();
        if (!originStat)
            throw new Error('origin or target is not directory');
        if (!fs.existsSync(targetPath))
            createDir(targetPath);
        const entries = fs.readdirSync(origin, { withFileTypes: true });
        for (const entry of entries) {
            const sourceChildrenPath = path.resolve(origin, entry.name), destChildrenPath = path.resolve(targetPath, entry.name);
            // 是否忽略此路径的移动
            if (typeof ignore === 'function' &&
                isType(ignore, ['function', 'asyncfunction']) &&
                (await ignore(sourceChildrenPath, destChildrenPath))) {
                continue;
            }
            // 此路径是否覆盖, 覆盖时，只能文件不能目录
            let isCover = false;
            if (fs.existsSync(destChildrenPath) && !entry.isDirectory()) {
                if ((isType(cover, ['boolean']) && cover) ||
                    (typeof cover === 'function' &&
                        (await cover(sourceChildrenPath, destChildrenPath)))) {
                    isCover = true;
                    fs.unlinkSync(destChildrenPath);
                }
                else {
                    continue;
                }
            }
            if (entry.isDirectory()) {
                await copyDirectory(sourceChildrenPath, destChildrenPath, cover, ignore);
            }
            else {
                copyFile(sourceChildrenPath, destChildrenPath, isCover);
            }
        }
    };
    /**
     * 移除文件, 当传递的是文件，则删除文件，传递的是目录，则递归删除目录
     * @param { string } targetPath 文件路径
     * */
    const removeFileOrDir = (targetPath) => {
        if (!fs.existsSync(targetPath))
            return;
        const stats = fs.statSync(targetPath);
        if (stats.isDirectory())
            fs.rmSync(targetPath, { recursive: true });
        else
            fs.unlinkSync(targetPath);
    };
    /**
     * 检测权限，若权限不为读写，则赋值为读写
     * @param { string } targetPath 文件路径
     * **/
    const checkXPermission = (targetPath) => {
        fs.accessSync(targetPath, fs.constants.X_OK);
        fs.chmodSync(targetPath, fs.constants.S_IXUSR);
    };
    /**
     * 检测文件是否为只读权限
     * @param { string } targetPath 文件路径
     * **/
    const checkReadPermission = (targetPath) => {
        fs.accessSync(targetPath, fs.constants.R_OK);
    };
    /**
     * 递归删除目录, 手动方式删除（兼容老版本Node）
     * @param { string } dirPath 目录的路径
     * @param { Array<string> } whiteList 删除文件的白名单
     * **/
    const dropCleanFolder = (dirPath, whiteList = []) => {
        if (fs.existsSync(dirPath)) {
            const files = fs.readdirSync(dirPath);
            for (const file of files) {
                const filePath = path.join(dirPath, file);
                if (fs.lstatSync(filePath).isDirectory()) {
                    dropCleanFolder(filePath, whiteList);
                }
                else {
                    if (!whiteList.includes(filePath)) {
                        fs.unlinkSync(filePath);
                    }
                }
            }
            if (!whiteList.includes(dirPath)) {
                fs.rmdirSync(dirPath);
            }
        }
    };
    /**
     * 当文件存在时，则合并内容，反之创建文件
     * @param { string } source 源路径
     * @param { string } targetPath 目标路径
     * @param { Object } options 写入或创建文件的参数
     * **/
    const mergeOrCreateFile = (source, targetPath, options = {}) => {
        options = srcExports.recursive({ wrap: false, jsonOrArray: false, tabWidth: 4 }, options);
        const existsSource = fs.existsSync(source), existsTarget = fs.existsSync(targetPath);
        if (!existsSource)
            throw new Error('source or target path can not be null');
        if (!existsTarget)
            return fs.copyFileSync(source, targetPath);
        const sourceContent = fs.readFileSync(source, { encoding: 'utf-8' });
        if (options.jsonOrArray) {
            const source = JSON.parse(sourceContent), target = JSON.parse(fs.readFileSync(targetPath, {
                encoding: 'utf-8'
            }));
            fs.writeFileSync(targetPath, JSON.stringify(srcExports.recursive(source, target), null, options.tabWidth), {
                encoding: 'utf-8'
            });
        }
        else {
            fs.appendFileSync(targetPath, `${options.wrap ? '\n' : ''}${sourceContent}`, { encoding: 'utf-8' });
        }
    };
    /**
     * 判断一个目录是否是盘符目录
     * @param { string } targetPath 目标路径
     * **/
    const isDriveDirectory = (targetPath) => {
        targetPath = path.resolve(targetPath);
        return targetPath === path.parse(targetPath).root;
    };
    /**
     * 向上层目录层级执行一个函数，直到函数返回成功或遇到盘符目录为止
     * @param { string } targetPath 需要执行函数的目录
     * @param { Function } cb 执行的自定义函数, 此函数返回true则终止执行，反之执行至盘符目录为止
     * **/
    const parentExecHandlerPromise = (targetPath, cb) => {
        return new Promise((resolve) => {
            if (isDriveDirectory(targetPath))
                return resolve('');
            const recursionExecHandler = () => resolve(parentExecHandlerPromise(path.dirname(targetPath), cb));
            if (isType(cb, 'asyncfunction')) {
                cb(targetPath)
                    .then((result) => {
                    if (!result)
                        throw new Error('');
                    return resolve(result);
                })
                    .catch(() => {
                    return recursionExecHandler();
                });
            }
            else {
                try {
                    const result = cb(targetPath);
                    if (result)
                        return resolve(result);
                    else
                        throw new Error('');
                }
                catch (e) {
                    return recursionExecHandler();
                }
            }
        });
    };
    /**
     * 向上查询文件的存在目录
     * @param { string } targetPath 基准目录
     * @param { string } handler 文件名称或执行函数
     * @returns { string } 查询到的文件目录
     * **/
    const findParentFile = (targetPath, handler) => {
        return parentExecHandlerPromise(targetPath, async (cwd) => {
            let result = null;
            if (isType(handler, 'string')) {
                result = fs.existsSync(path.resolve(cwd, handler));
            }
            else if (isType(handler, 'function')) {
                result = handler(cwd);
            }
            else if (isType(handler, 'asyncfunction')) {
                result = await handler(cwd);
            }
            else {
                throw new Error('invalid handler parameter');
            }
            return result ? cwd : result;
        });
    };
    /**
     * 给定一个目录，返回这个目录的根目录
     * @param { string } value 给定的目录字符串
     * @returns { string } 根目录字符串
     * **/
    const findRootParentPath = (value) => {
        if (!value.trim())
            return value;
        value = value.replaceAll('//', '/');
        const parentPath = path.dirname(value);
        if (['.', '/'].includes(parentPath))
            return value;
        else
            return findRootParentPath(parentPath);
    };
    /**
     * 查看一个路径下是否存在列表中这些文件，只要有一个满足则返回 true
     * @param { string } basicPath 查询的路径
     * @param { Array<string> } fileNameList 需要查询的文件名称列表
     * @returns { string } 查询到的文件名称
     * **/
    const getExistsFilePath = (basicPath = process.cwd(), fileNameList) => {
        for (const item of fileNameList) {
            const filePath = path.resolve(basicPath, item);
            if (fs.existsSync(filePath))
                return filePath;
        }
        return '';
    };
    /**
     * 将 blob 转换为 string 字符串
     * @param { Blob } blob 二进制数据内容
     * **/
    const blobToString = (blob) => {
        return new Promise((resolve) => {
            const fileRender = new FileReader();
            fileRender.onload = () => {
                resolve(fileRender.result);
            };
            fileRender.readAsText(blob);
        });
    };

    /**
     * 获取浏览器属性
     * @returns { string } name 浏览器名称
     * @returns { string } version 浏览器版本
     * **/
    const getBrowserInfo = () => {
        const userAgent = window.navigator.userAgent;
        let browserName = '', browserVersion = '';
        if (/Chrome/i.test(userAgent)) {
            browserName = 'Chrome';
        }
        else if (/Firefox/i.test(userAgent)) {
            browserName = 'Firefox';
        }
        else if (/Safari/i.test(userAgent)) {
            browserName = 'Safari';
        }
        else if (/Opera|OPR/i.test(userAgent)) {
            browserName = 'Opera';
        }
        else if (/Edge/i.test(userAgent)) {
            browserName = 'Edge';
        }
        else if (/MSIE/i.test(userAgent) || /Trident/i.test(userAgent)) {
            browserName = 'IE';
        }
        else {
            browserName = 'Unknown';
        }
        const versionMatch = userAgent.match(/(Chrome|Firefox|Safari|Opera|Edge|IE)\/?\s*(\.?\d+(\.\d+)*)/i);
        if (versionMatch && versionMatch.length >= 3) {
            browserVersion = versionMatch[2];
        }
        else {
            browserVersion = 'Unknown';
        }
        return {
            name: browserName,
            version: browserVersion
        };
    };

    exports.blobToString = blobToString;
    exports.checkReadPermission = checkReadPermission;
    exports.checkXPermission = checkXPermission;
    exports.copyDirectory = copyDirectory;
    exports.copyFile = copyFile;
    exports.createDir = createDir;
    exports.createFile = createFile;
    exports.debounce = debounce;
    exports.differenceArrayList = differenceArrayList;
    exports.dropCleanFolder = dropCleanFolder;
    exports.execCommand = execCommand;
    exports.exists = exists;
    exports.findParentFile = findParentFile;
    exports.findRootParentPath = findRootParentPath;
    exports.findString = findString;
    exports.flatJSON = flatJSON;
    exports.getAppData = getAppData;
    exports.getBrowserInfo = getBrowserInfo;
    exports.getExistsFilePath = getExistsFilePath;
    exports.getHome = getHome;
    exports.getPackageMangerName = getPackageMangerName;
    exports.getPidByName = getPidByName;
    exports.getReferToAppData = getReferToAppData;
    exports.getSystemInfo = getSystemInfo;
    exports.getType = getType;
    exports.hasProperty = hasProperty;
    exports.intersectionArrayList = intersectionArrayList;
    exports.isActiveProcessByName = isActiveProcessByName;
    exports.isActiveProcessByPid = isActiveProcessByPid;
    exports.isEmptyArray = isEmptyArray;
    exports.isEmptyJSON = isEmptyJSON;
    exports.isType = isType;
    exports.isValidUrl = isValidUrl;
    exports.killProcessName = killProcessName;
    exports.killProcessPid = killProcessPid;
    exports.mergeOrCreateFile = mergeOrCreateFile;
    exports.packageMangerViewer = packageMangerViewer;
    exports.readExistsFile = readExistsFile;
    exports.readForTypeFileDir = readForTypeFileDir;
    exports.removeFileOrDir = removeFileOrDir;
    exports.sleep = sleep;
    exports.splitJsonToContent = splitJsonToContent;
    exports.throttle = throttle;
    exports.unionArrayList = unionArrayList;
    exports.validType = validType;

}));
